package com.xhtt.modules.task.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhtt.common.exception.RRException;
import com.xhtt.common.utils.Constant;
import com.xhtt.common.utils.CopyUtils;
import com.xhtt.common.utils.PageUtils;
import com.xhtt.common.utils.Query;
import com.xhtt.modules.cfg.entity.CfgIsland;
import com.xhtt.modules.cfg.entity.CfgStand;
import com.xhtt.modules.cfg.service.CfgIslandService;
import com.xhtt.modules.cfg.service.CfgStandService;
import com.xhtt.modules.msg.entity.MsgInfo;
import com.xhtt.modules.msg.entity.MsgUser;
import com.xhtt.modules.msg.service.MsgInfoService;
import com.xhtt.modules.msg.service.MsgUserService;
import com.xhtt.modules.sys.entity.SysDeptEntity;
import com.xhtt.modules.sys.entity.SysUserEntity;
import com.xhtt.modules.sys.service.SysDeptService;
import com.xhtt.modules.sys.service.SysUserService;
import com.xhtt.modules.task.dao.TaskCarTaskMapper;
import com.xhtt.modules.task.entity.TaskCarPlan;
import com.xhtt.modules.task.entity.TaskCarSeo;
import com.xhtt.modules.task.entity.TaskCarTask;
import com.xhtt.modules.task.entity.TaskCarTaskUser;
import com.xhtt.modules.task.model.car.ArrangeUserModel;
import com.xhtt.modules.task.model.car.AssignTaskModel;
import com.xhtt.modules.task.model.car.CarTaskListModel;
import com.xhtt.modules.task.model.car.CarTaskSubModel;
import com.xhtt.modules.task.model.msg.ShiftsModel;
import com.xhtt.modules.task.model.msg.ShiftsToUserModel;
import com.xhtt.modules.task.schedule.RowCarSchedule;
import com.xhtt.modules.task.service.TaskCarPlanService;
import com.xhtt.modules.task.service.TaskCarSeoService;
import com.xhtt.modules.task.service.TaskCarTaskService;
import com.xhtt.modules.task.service.TaskCarTaskUserService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 排车任务-主任务 服务实现类
 * </p>
 *
 * @author feipc
 * @since 2019-02-27
 */
@Service
public class TaskCarTaskServiceImpl extends ServiceImpl<TaskCarTaskMapper, TaskCarTask> implements TaskCarTaskService {
    @Autowired
    private CfgStandService cfgStandService;
    @Autowired
    private CfgIslandService cfgIslandService;
    @Autowired
    private TaskCarPlanService taskCarPlanService;
    @Autowired
    private TaskCarTaskUserService carTaskUserService;
    @Autowired
    private MsgInfoService msgInfoService;
    @Autowired
    private MsgUserService msgUserService;
    @Autowired
    private RowCarSchedule rowCarSchedule;
    @Resource
    private ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysDeptService sysDeptService;
    @Autowired
    private TaskCarSeoService taskCarSeoService;


    @Override
    public PageUtils taskList(Map<String, Object> params) {
        Page<CarTaskListModel> page = new Query<CarTaskListModel>(params).getPage();
        List<CarTaskListModel> list = baseMapper.taskList(page, params);
        if (CollectionUtils.isNotEmpty(list)) {
            List<CarTaskSubModel> standList;
            CarTaskSubModel subModel;
            for (CarTaskListModel md : list) {
                List<CfgStand> stands = cfgStandService.list(new LambdaQueryWrapper<CfgStand>().eq(CfgStand::getIslandId, md.getIslandId()).eq(CfgStand::getStatus, 1));
                if (CollectionUtils.isNotEmpty(stands)) {
                    standList = new ArrayList<>();
                    for (CfgStand cs : stands) {
                        int stopGroundCount = taskCarPlanService.count(new LambdaQueryWrapper<TaskCarPlan>().eq(TaskCarPlan::getStageId, cs.getId()).isNotNull(TaskCarPlan::getDateInvoice).isNull(TaskCarPlan::getDateWeigh));//已经开票但未过磅的是停车场
                        List<Map<String, Object>> l = baseMapper.getWaitingCount(cs.getId());//已经过磅但是还未分配任务的是待装车
                        int waitingCount = Integer.valueOf(l.get(0).get("count").toString());
                        String product = null == l.get(0).get("product") ? "" : l.get(0).get("product").toString();
                        int loadingCount = baseMapper.getLoadingCount(cs.getId());//已经分配任务的是装车中
                        subModel = new CarTaskSubModel(cs.getId(), cs.getName(), product, stopGroundCount, waitingCount, loadingCount);
                        standList.add(subModel);
                    }
                    md.setStandList(standList);
                }
            }
        }
        page.setRecords(list);
        return new PageUtils(page);
    }

    @Override
    public LocalDateTime getUserFinishTime(Integer userId) {
        int count = this.count(new LambdaQueryWrapper<TaskCarTask>().eq(TaskCarTask::getUserId, userId));
        //没有这个人的话说明他还从没做过任务
        if (0 == count) {
            return LocalDateTime.MIN;//返回一个最小日期，再做判断
        }

        count = this.count(new LambdaQueryWrapper<TaskCarTask>().eq(TaskCarTask::getUserId, userId).isNull(TaskCarTask::getFinishDate));
        //判断完成时间  存在无完工时间的说明还在工作中
        if (0 < count) {
            return null;
        }

        TaskCarTask t = this.getOne(new LambdaQueryWrapper<TaskCarTask>().eq(TaskCarTask::getUserId, userId).isNotNull(TaskCarTask::getFinishDate).orderByDesc(TaskCarTask::getFinishDate).select(TaskCarTask::getId, TaskCarTask::getFinishDate).last("limit 1"));
        return t.getFinishDate();
    }

    @Override
    @Transactional
    public void assignTask(AssignTaskModel model) {
        //先查出在台上的所有满足条件的plan（已经过磅但是还未分配任务）
//        List<TaskCarPlan> planList = taskCarPlanService.list(new LambdaQueryWrapper<TaskCarPlan>().in(TaskCarPlan::getStageId, model.getStandIds()).isNotNull(TaskCarPlan::getDateWeigh));

//        Set<Integer> planIds = planList.stream().map(taskCarPlan -> taskCarPlan.getId()).collect(Collectors.toSet());
        //分配过的plan不再重新分配
//        TaskCarTask nt = new TaskCarTask();
//        nt.setUserId(model.getUserId());
//        this.update(nt, new UpdateWrapper<TaskCarTask>().in(TaskCarTask.CarPlanId, planIds).isNull(TaskCarTask.UserId));
        CfgIsland island = cfgIslandService.getById(model.getIslandId());
        if (null == island || null == model.getUserId()) {
            throw new RRException("参数不能为空");
        }
        if (island.getStatus() == -1) {
            throw new RRException("已被删除无法分配");
        }
        SysUserEntity user = sysUserService.getOne(new LambdaQueryWrapper<SysUserEntity>().eq(SysUserEntity::getUserId, model.getUserId()).select(SysUserEntity::getUserId, SysUserEntity::getLoginStatus));
        if (null == user || user.getLoginStatus().intValue() == 0) {
            throw new RRException("用户不在线，无法指派");
        }
        //如果他之前的别的岛上，那么把之前的岛设置为null
        cfgIslandService.removeUser(model.getUserId());
        island.setUserId(model.getUserId());
        cfgIslandService.updateById(island);

        //设置完人后要推任务   车过磅后也要推任务 ,任务提交也要推
        //获取这个岛的台
        Integer islandId = island.getId();
        Integer userId = model.getUserId();
        List<CfgStand> standList = cfgStandService.list(new LambdaQueryWrapper<CfgStand>().eq(CfgStand::getIslandId, islandId).eq(CfgStand::getStatus, 1));
        if (CollectionUtils.isNotEmpty(standList)) {
            rowCarSchedule.pushRowCarTask(userId, standList);
        }
    }

    @Override
    public PageUtils taskWorkingList(Map<String, Object> params) {
        Page<TaskCarPlan> page = new Query<TaskCarPlan>(params).getPage();
        List<TaskCarPlan> list = baseMapper.taskWorkingList(page, params);
        page.setRecords(list);
        return new PageUtils(page);
    }

    @Override
    @Transactional
    public void changeShifts(SysUserEntity user, TaskCarTaskUser tu) {
        Integer selfId = user.getUserId().intValue();
        //查询自己没完成的任务
        List<TaskCarTask> list = this.shiftsList(selfId);
        List<String> details = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        if (null == tu.getTargetUserId()) {
            // 发给组长
            SysUserEntity leader = sysUserService.getTeamLeaderByUser(user.getUserId().intValue());
            if (null == leader) {
                throw new RRException("没有组长");
            }
            list.forEach(taskCarTask -> {
                taskCarTask.setUserId(0);//先分给一个不存在的人，表示待分配
                details.add(taskCarTask.getStageName());
            });
            this.updateBatchById(list);

            carTaskUserService.saveShiftDetail(user, list);
            //自己从岛上撤下来
            cfgIslandService.update(new CfgIsland(), new UpdateWrapper<CfgIsland>().set(CfgIsland.USERID, null).eq(CfgIsland.USERID, user.getUserId()));
            //发消息
            taskExecutor.submit(() -> {
                if (CollectionUtils.isNotEmpty(details)) {
                    List<Integer> taskIdList = list.stream().map(t -> t.getId()).collect(Collectors.toList());
                    ShiftsToUserModel model = new ShiftsToUserModel(String.join("、", details), user.getName(), "car", null, taskIdList);
                    model.setSelfUser(user.getName());
                    model.setDetail(String.join("、", details));

                    List<MsgInfo> msgList = new ArrayList();
                    Set<Integer> userIds = new HashSet<>();
                    MsgInfo msg = new MsgInfo("交接班信息", "排车任务-分配人员", "排车任务", JSON.toJSONString(model));
                    userIds.add(leader.getUserId().intValue());
                    msg.setUserIdList(userIds);
                    msgList.add(msg);
                    msgInfoService.saveMsgBatch(msgList);
                }
            });
        } else {
            list.forEach(taskCarTask -> {
                taskCarTask.setUserId(tu.getTargetUserId());
                details.add(taskCarTask.getStageName());
            });
            this.updateBatchById(list);

            carTaskUserService.saveShiftDetail(user, tu, list);
            //还要把自己的岛也让给别人（理论上只会有一个岛）
            cfgIslandService.update(new CfgIsland(), new UpdateWrapper<CfgIsland>().set(CfgIsland.USERID, null).eq(CfgIsland.USERID, tu.getTargetUserId()));//目标人还要先放弃自己的岛
            CfgIsland island = new CfgIsland();
            island.setUserId(tu.getTargetUserId());
            cfgIslandService.update(island, new LambdaQueryWrapper<CfgIsland>().eq(CfgIsland::getUserId, selfId));

            //发消息
            taskExecutor.submit(() -> {
                if (CollectionUtils.isNotEmpty(details)) {
                    ShiftsModel model = new ShiftsModel();
                    model.setSelfUser(user.getName());
                    model.setTargetUser(tu.getUserName());
                    model.setDetail(String.join("、", details));

                    List<Integer> userIds = new ArrayList<>();
                    userIds.add(tu.getTargetUserId());
                    MsgInfo msg = new MsgInfo("交接班信息", "排车任务", "排车任务", JSON.toJSONString(model));
                    msgUserService.insertBatch(msg, userIds);
                }
            });
        }
    }

    @Override
    public int getLoadingCount(Integer standId) {
        return baseMapper.getLoadingCount(standId);
    }

    @Override
    public TaskCarPlan getWaitingTask(Integer standId) {
        return baseMapper.getWaitingTask(standId);
    }

    @Override
    public void operComplete(TaskCarTask taskCarTask, Integer userId) {
        TaskCarTask db = this.getOne(new LambdaQueryWrapper<TaskCarTask>().eq(TaskCarTask::getCarPlanId, taskCarTask.getCarPlanId()));
        if (null == db) {
            throw new RRException("对象不存在");
        }
        CopyUtils.copyProperties(taskCarTask, db);
        if (CollectionUtils.isNotEmpty(taskCarTask.getFiles())) {
            db.setPhoto(JSON.toJSONString(taskCarTask.getFiles()));
        }
        db.setFinishDate(LocalDateTime.now());
        this.updateById(db);

        TaskCarPlan plan = taskCarPlanService.getOne(new LambdaQueryWrapper<TaskCarPlan>().eq(TaskCarPlan::getId, taskCarTask.getCarPlanId()));
//        taskExecutor.submit(() -> {
//            //做完一个,推新任务
//            List<CfgStand> standList = new ArrayList<>();
//            CfgStand stand = new CfgStand();
//            stand.setId(plan.getStageId());
//            standList.add(stand);
//            rowCarSchedule.pushRowCarTask(userId, standList);
//        });

        //发消息
        taskExecutor.submit(() -> {
            //还要获取装车台名字
            CfgStand stand = cfgStandService.getOne(new LambdaQueryWrapper<CfgStand>().eq(CfgStand::getId, plan.getStageId()).select(CfgStand::getId, CfgStand::getName));
            plan.setStageName(null == stand ? "" : stand.getName());
            MsgInfo msg = new MsgInfo("排车任务", "排车任务", "装车完成", JSON.toJSONString(plan));
            //找到装车组的狗班长
            SysDeptEntity team = sysDeptService.getOne(new LambdaQueryWrapper<SysDeptEntity>().eq(SysDeptEntity::getName, Constant.ZCZ).eq(SysDeptEntity::getType, 2).select(SysDeptEntity::getDeptId));
            if (null != team) {
                SysUserEntity leader = sysUserService.getTeamLeader(team.getDeptId());
                if (null != leader) {
                    List<Integer> userIds = new ArrayList<>();
                    userIds.add(leader.getUserId().intValue());
                    msgUserService.insertBatch(msg, userIds);
                }
            }
        });
        //把完成的任务要同步到seo表里面，恶心的业务简直日了狗了
        taskExecutor.submit(() -> {
            TaskCarSeo seo = taskCarPlanService.dataToSeo(taskCarTask.getCarPlanId());
            taskCarSeoService.save(seo);
        });
    }

    @Override
    public List<TaskCarPlan> getAllWaitingTasks() {
        return baseMapper.getAllWaitingTasks();
    }

    @Override
    public List<TaskCarTask> shiftsList(Integer selfId) {
        return baseMapper.shiftsList(selfId, null);
    }

    @Override
    public List<Map<String, Object>> carForUser(Map<String, Object> params) {
        return baseMapper.carForUser(params);
    }

    @Override
    public List<Map<String, Object>> carForStand(Map<String, Object> params) {
        return baseMapper.carForStand(params);
    }

    @Override
    @Transactional
    public void arrangeUser(ArrangeUserModel model, SysUserEntity user) {
        Integer msgId = model.getMsgId();
        List<Integer> taskIdList = model.getTaskIdList();
        TaskCarTaskUser taskUser = model.getTaskUser();
        if (CollectionUtils.isEmpty(taskIdList) || null == taskUser || null == taskUser.getTargetUserId() || null == msgId) {
            throw new RRException("参数有误");
        }
        List<TaskCarTask> list = baseMapper.shiftsList(null, taskIdList);
        List<String> details = new ArrayList<>();
        Set<Integer> islandIdSet = list.stream().map(t -> t.getIslandId()).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(islandIdSet)) {
            return;
        }
        list.forEach(taskCarTask -> {
            taskCarTask.setUserId(taskUser.getTargetUserId());
            details.add(taskCarTask.getStageName());
        });
        this.updateBatchById(list);

        carTaskUserService.saveShiftDetail(user, taskUser, list);

        //还要把自己的岛也让给别人（理论上只会有一个岛）
        cfgIslandService.update(new CfgIsland(), new UpdateWrapper<CfgIsland>().set(CfgIsland.USERID, null).eq(CfgIsland.USERID, taskUser.getTargetUserId()));//目标人还要先放弃自己的岛

        CfgIsland island = new CfgIsland();
        island.setUserId(taskUser.getTargetUserId());
        cfgIslandService.update(island, new LambdaQueryWrapper<CfgIsland>().in(CfgIsland::getId, islandIdSet));//把这些任务所在的岛给这个人
        //删掉这条消息(假删，只删人的关系，这样人就看不到了 )
        msgUserService.remove(new LambdaQueryWrapper<MsgUser>().eq(MsgUser::getMsgId, msgId));

        //发消息
        taskExecutor.submit(() -> {
            if (CollectionUtils.isNotEmpty(details)) {
                ShiftsModel sm = new ShiftsModel();
                sm.setDetail(String.join("、", details));
                sm.setSelfUser(user.getName());
                sm.setTargetUser(taskUser.getUserName());

                List<Integer> userIds = new ArrayList<>();
                userIds.add(taskUser.getTargetUserId());

                //构造model
//                Integer planId = this.getOne(new LambdaQueryWrapper<TaskCarTask>().eq(TaskCarTask::getId,taskIdList.get(0)).select(TaskCarTask::getCarPlanId)).getCarPlanId();
//                TaskCarPlan carPlan = taskCarPlanService.getById(planId);
//                CfgStand stand = cfgStandService.getOne(new LambdaQueryWrapper<CfgStand>().eq(CfgStand::getId, carPlan.getStageId()).select(CfgStand::getName));
//                carPlan.setStageName(stand.getName());
                MsgInfo msg = new MsgInfo("交接班信息", "排车任务", "排车任务", JSON.toJSONString(sm));
                msgUserService.insertBatch(msg, userIds);
            }
        });
    }

}
